package top.lshaci.learning.springboot.security.config;

import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * SecurityConfig
 *
 * @author lshaci
 * @since 1.0.0
 */
@Configuration
@AllArgsConstructor
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final PasswordEncoder passwordEncoder;

    private final UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.exceptionHandling()
                // 没有权限由指定 handler 进行处理
                .accessDeniedHandler((request, response, accessDeniedException) -> {
                    response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
                    response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                    Map<String, Object> map = new HashMap<>(2);
                    map.put("code", 40003);
                    map.put("msg", "您没有权限进行此操作");
                    response.getWriter().write(JSONUtil.toJsonStr(map));
                })
                // 没有权限跳转到指定页面
//                .accessDeniedPage("/403.html")
        ;

        // 自定义自己编写的登录页面
        http.formLogin()
                // 登录页面设置
                .loginPage("/login.html")
                // 登录访问路径
                .loginProcessingUrl("/user/login")
                // 登录成功后，跳转路径
                .defaultSuccessUrl("/hello/index")
        ;

        http.authorizeRequests()
                // 设置哪些路径可以直接访问，不需要认证（登录）
                .antMatchers("/", "/user/login", "/login.html").permitAll()
//                    .antMatchers("/hello/index").hasAuthority("admins") // 该路径需要admin权限才能访问
//                    .antMatchers("/hello/index").hasAnyAuthority("admin", "manager")
//                .antMatchers("/hello/index").hasRole("admins")
//                    .antMatchers("/hello/index").hasAnyRole("admin,manager")
//                .antMatchers("/permission/p1").hasAuthority("p1")
//                .antMatchers("/permission/p2").hasAuthority("p2")
                // 任何请求，只要已认证（登录）就可以访问
                .anyRequest().authenticated()
        ;

        // csrf配置
        http.csrf()
                // 关闭csrf防护
                .disable()
        ;

        // 退出配置
        http.logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login.html")
        ;
    }
}
